package cog.support.util.map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 用来存储短暂对象的缓存类，实现Map接口，内部有一个定时器用来清除过期（30秒）的对象。
 * 为避免创建过多线程，没有特殊要求请使用getDefault()方法来获取本类的实例。
 * @author www.zuidaima.com
 * @param <K> 
 * @param <V> 
 */  
  
public class TimedCleanHashMap<K, V>  implements ConcurrentMap<K,V>, Serializable {
    private Logger logger = LoggerFactory.getLogger(TimedCacheHashMap.class);

    private ConcurrentMap<K,TimerValue<K,V>> map;
    private Timer timerDatabaseInsert;
    private long timeOut;

    public TimedCleanHashMap(long timeOut){
        this.timeOut = timeOut;
        this.map = new ConcurrentHashMap<>();
        this.timerDatabaseInsert  = new Timer();
        this.timerDatabaseInsert.schedule(new TimerTask() {
            @Override
            public void run() {
                clearTimeOutValue();
            }
        }, 1000, 1000 * 60);
    }

    public void clearTimeOutValue(){
        Collection<TimerValue<K,V>>  valueList = map.values();
        Collection<K> removeColl = new ArrayList<>();
        for(TimerValue<K,V> v : valueList){
            if(System.currentTimeMillis() >= v.getTimeMillis() + timeOut){
                removeColl.add(v.getKey());
            }
        }

        for(K key : removeColl) map.remove(key);
    }


    @Override
    public int size() {
        return map.size();
    }

    @Override
    public boolean isEmpty() {
        return map.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return map.containsKey(key);
    }

    @Override
    public boolean containsValue(Object value) {
        return false;
    }

    @Override
    public V get(Object key) {
        TimerValue<K,V> v = map.get(key);
        return v!=null ? v.getValue() : null;
    }

    @Override
    public V put(K key, V value) {
        map.put(key,new TimerValue<K,V>(key,value));
        return value;
    }

    @Override
    public V remove(Object key) {
        TimerValue<K,V> v = map.remove(key);
        return v!=null ? v.getValue() : null;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> m) {

    }

    @Override
    public void clear() {
        map.clear();
    }

    @Override
    public Set<K> keySet() {
        return map.keySet();
    }

    @Override
    public Collection<V> values() {
        Collection<TimerValue<K,V>> values = map.values();
        Collection<V> returnValue = new ArrayList<V>();
        for(TimerValue<K,V> v : values)
            returnValue.add(v.getValue());
        return returnValue;
    }

    @Override
    public Set<Entry<K, V>> entrySet() {
        return null;
    }

    @Override
    public V putIfAbsent(K key, V value) {
        return null;
    }

    @Override
    public boolean remove(Object key, Object value) {
        return false;
    }

    @Override
    public boolean replace(K key, V oldValue, V newValue) {
        return false;
    }

    @Override
    public V replace(K key, V value) {
        return null;
    }
}